import numpy as np    
  
# 定义一个Matrix类，该类是对于numpy的数组类型的包装
# 只需访问该类的成员_matrix即可将其视为矩阵进行运算
# 因此它与矩阵是相容的，关于矩阵的方法都可以作用域此类
class Matrix:    
    # 初始化方法，接收一个二维的方形的NumPy数组作为输入  
    def __init__(self, matrix):   
        if not isinstance(matrix, np.ndarray) or matrix.ndim != 2:    
            raise ValueError("输入的矩阵必须是二维的NumPy数组。")    
        if matrix.shape[0] != matrix.shape[1]:    
            raise ValueError("输入的矩阵必须是方阵。")   
         
        self._matrix = matrix    
    
    # 将矩阵中非零元素变为1，实现二值化  
    def binarize(self):    
        self._matrix[self._matrix != 0] = 1         
        return self  
    
    # 计算矩阵的自反闭包  
    def r(self):    
        # 将矩阵与单位矩阵相加，得到自反闭包  
        tmp_matrix = self._matrix + np.eye(self._matrix.shape[0], dtype=int)    
        return Matrix(tmp_matrix).binarize() 
    
    # 计算矩阵的对称闭包  
    def s(self):  
        # 将矩阵与其转置矩阵相加，得到对称闭包  
        tmp_matrix = self._matrix + self._matrix.T    
        return Matrix(tmp_matrix).binarize() 
  
    # 计算矩阵的传递闭包  
    def t(self):   
        tmp_matrix = self._matrix.copy()  
        n = tmp_matrix.shape[0]  
        # 使用Floyd-Warshall算法计算传递闭包  
        for k in range(n):    
            for i in range(n):    
                for j in range(n):    
                    # 如果存在从i到k和从k到j的路径，则在i和j之间添加一条路径  
                    if tmp_matrix[i, k] and tmp_matrix[k, j]:    
                        tmp_matrix[i, j] = 1     
        return Matrix(tmp_matrix).binarize()  
    
    # 定义该类的表达方法  
    def __str__(self):      
        return str(self._matrix)    
    
# 测试样例
n = np.random.randint(2, 10)
A = Matrix(np.random.choice([0, 1], size=(n, n)))
     
print("原矩阵为：")    
print(A)    
print()    
    
print("自反闭包为：")    
print(A.r())    
print()    
     
print("对称闭包为：")    
print(A.s())    
print()    
     
print("传递闭包为：")    
print(A.t())    
print()